﻿using Host.Configuration;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;

namespace Host.JWT
{
    public class JwtToken
    {
        /// <summary>
        /// 加密密码
        /// </summary>
        public const string tokenKey = "ROURS";
        private TokenConfigurations _configuration;

        public JwtToken(TokenConfigurations configurations)
        {
            _configuration = configurations;
        }

        /// <summary>
        /// 创建JWT的Token
        /// </summary>
        /// <param name="claims"></param>
        /// <param name="expiration"></param>
        /// <returns></returns>
        private string CreateAccessToken(IEnumerable<Claim> claims, TimeSpan? expiration = null)
        {
            //获取当前时间
            var now = DateTime.UtcNow;
            //获取配置文件的参数
            var jwtSecurityToken = new JwtSecurityToken(
                issuer: _configuration.Issuer,
                audience: _configuration.Audience,
                claims: claims,
                notBefore: now,
                expires: now.Add(expiration ?? _configuration.Expiration),
                signingCredentials: _configuration.SigningCredentials
            );

            return new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
        }

        /// <summary>
        /// 创建JWT的Claims
        /// </summary>
        /// <param name="identity"></param>
        /// <returns></returns>
        private static List<Claim> CreateJwtClaims(ClaimsIdentity identity)
        {
            var claims = identity.Claims.ToList();
            var nameIdClaim = claims.First(c => c.Type == ClaimTypes.NameIdentifier);
            //添加claims
            claims.AddRange(new[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, nameIdClaim.Value),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.Now.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
            });

            return claims;
        }

        /// <summary>
        /// 获取未加密Token
        /// </summary>
        /// <param name="identity">登录用户的Claims</param>
        /// <returns></returns>
        public string GetToken(ClaimsIdentity identity)
        {
            return CreateAccessToken(CreateJwtClaims(identity));
        }

        /// <summary>
        /// 获取加密Token
        /// </summary>
        /// <param name="identity">登录用户的Claims</param>
        /// <returns></returns>
        public string GetEncryptToken(ClaimsIdentity identity)
        {
            return AbpCipherAlgorithm.Encrypt(CreateAccessToken(CreateJwtClaims(identity)));
        }

        /// <summary>
        /// 解析Token
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool SerializeToken(string token)
        {
            try
            {
                //创建JWT的Token处理程序并读取Token
                var jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token);
                //判断发行人是否一致
                return jwtToken.Claims.Any(x => x.Issuer == _configuration.Issuer) == true ? true : false;
            }
            catch
            {
                return false;
            }
        }
    }
}
